package org.zhuxian.cn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zhuxian.cn.entity.*;
import org.zhuxian.cn.entity.DTO.EquipmentBuildsDTO;
import org.zhuxian.cn.entity.VO.EquipmentBuildsVO;
import org.zhuxian.cn.mapper.EquipmentBuildsMapper;
import org.zhuxian.cn.service.EquipmentBuildsService;
import org.zhuxian.cn.service.EquipmentService;
import org.zhuxian.cn.service.InlayService;
import org.zhuxian.cn.service.TalismanService;
import org.zhuxian.cn.service.UserService;
import org.zhuxian.cn.utils.RedisUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class EquipmentBuildsServiceImpl implements EquipmentBuildsService {
    @Autowired
    private EquipmentService equipmentService;
    @Autowired
    private InlayService inlayService;
    @Autowired
    private TalismanService talismanService;
    @Autowired
    private UserService userService;
    @Autowired
    private EquipmentBuildsMapper equipmentBuildsMapper;
    @Autowired
    private RedisUtils redisUtils;

    private static String RECOMMENDEQUIPMENTBUILDS_KEY = "recommendEquipmentBuilds";
    private static String EQUIPMENTBUILD_KEY = "equipmentBuild";

    /**
     * 根据配装门派获取推荐配装
     *
     * @param buildClass 配装门派
     * @return 推荐配装列表
     */
    @Override
    public List<RecommendEquipmentBuilds> getRecommendEquipmentBuilds(String buildClass) {
        try {
            QueryWrapper<EquipmentBuilds> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("build_class", buildClass);
            queryWrapper.ne("like_count_statistics", 0);
            queryWrapper.orderByDesc("like_count_statistics");
            queryWrapper.last("LIMIT 5");
            List<EquipmentBuilds> equipmentBuilds = equipmentBuildsMapper.selectList(queryWrapper);

            List<RecommendEquipmentBuilds> recommendEquipmentBuilds = new ArrayList<>();
            for (EquipmentBuilds equipmentBuild : equipmentBuilds) {
                RecommendEquipmentBuilds recommendEquipmentBuild = new RecommendEquipmentBuilds();
                BeanUtils.copyProperties(equipmentBuild, recommendEquipmentBuild);
                recommendEquipmentBuild.setBuildAuthor(userService.getUserById(equipmentBuild.getUserId()).getNickname());
                recommendEquipmentBuilds.add(recommendEquipmentBuild);
            }

            return recommendEquipmentBuilds;
        } catch (Exception e) {
            log.error("获取推荐配装时出现异常，门派: {}", buildClass, e);
            return Collections.emptyList();
        }
    }


    /**
     * classname-青云、焚香、鬼王、合欢、灵汐
     *
     * @return 推荐每个classname前5的数据并返回
     */
    @Override
    public List<RecommendEquipmentBuilds> getRecommendEquipmentBuilds() {
        List<String> classNames = Arrays.asList("青云", "焚香", "鬼王", "合欢", "灵汐");
        List<RecommendEquipmentBuilds> allRecommendBuilds = new ArrayList<>();
        for (String className : classNames) {
            List<RecommendEquipmentBuilds> builds = getRecommendEquipmentBuilds(className);
            allRecommendBuilds.addAll(builds);
        }
        return allRecommendBuilds;
    }

    /**
     * 根据userid获取用户全部配装
     *
     * @param userId
     * @return
     */
    @Override
    public List<RecommendEquipmentBuilds> getEquipmentBuildsByUserId(Long userId) {
        List<EquipmentBuilds> equipmentBuilds = redisUtils.get(RECOMMENDEQUIPMENTBUILDS_KEY, List.class);
        if (equipmentBuilds == null || equipmentBuilds.isEmpty()) {
            equipmentBuilds = equipmentBuildsMapper.selectList(new QueryWrapper<EquipmentBuilds>().eq("user_id", userId));
            // 判空
            if (equipmentBuilds == null || equipmentBuilds.isEmpty()) {
                return Collections.emptyList();
            }

            redisUtils.setEx(RECOMMENDEQUIPMENTBUILDS_KEY + ":" + userId, equipmentBuilds, 3, TimeUnit.MINUTES);
        }

        // 根据user id获取昵称
        String nickname = userService.getUserById(userId).getNickname();

        // 定义推荐配装list
        List<RecommendEquipmentBuilds> recommendEquipmentBuilds = new ArrayList<>();
        for (EquipmentBuilds equipmentBuild : equipmentBuilds) {
            RecommendEquipmentBuilds recommendEquipmentBuild = new RecommendEquipmentBuilds();
            BeanUtils.copyProperties(equipmentBuild, recommendEquipmentBuild);
            recommendEquipmentBuild.setBuildAuthor(nickname);
            recommendEquipmentBuilds.add(recommendEquipmentBuild);
        }

        return recommendEquipmentBuilds;
    }

    /**
     * 根据userid和配装id删除配装
     *
     * @param userId
     * @return
     */
    @Override
    public boolean delEquipmentBuildsByUserIdAndId(Long id, Long userId) {
        if (!Objects.equals(equipmentBuildsMapper.selectById(id).getUserId(), userId)) {
            return false;
        }
        equipmentBuildsMapper.deleteById(id);
        return true;
    }

    /**
     * 根据配装 ID 获取配装信息
     *
     * @param id 配装 ID
     * @return 配装信息
     */
    @Override
    public EquipmentBuildsVO getEquipmentBuildsById(Integer id) {
        try {
            // redis查询
            EquipmentBuildsVO equipmentBuildsVO = redisUtils.get(EQUIPMENTBUILD_KEY + ":" + id, EquipmentBuildsVO.class);
            log.info("equipmentBuildsVO: {}", equipmentBuildsVO);
            if (equipmentBuildsVO != null) {
                return equipmentBuildsVO;
            }

            // mysql查询数据
            EquipmentBuilds equipmentBuilds = equipmentBuildsMapper.selectById(id);
            equipmentBuildsVO = new EquipmentBuildsVO();

            List<Equipment> equipments = new ArrayList<>();
            List<Inlay> inlays = new ArrayList<>();

            // 配装赋值
            for (int i = 0; i < equipmentBuilds.getEquipments().size(); i++) {
                Equipment equipment = equipmentBuilds.getEquipments().get(i);
                equipments.add(equipmentService.getEquipmentById(equipment.getId()));
            }

            for (int i = 0; i < equipmentBuilds.getInlays().size(); i++) {
                Inlay inlay = equipmentBuilds.getInlays().get(i);
                inlays.add(inlayService.getInlayById(inlay.getId()));
            }

            BeanUtils.copyProperties(equipmentBuilds, equipmentBuildsVO);
            equipmentBuildsVO.setEquipments(equipments);
            equipmentBuildsVO.setInlays(inlays);
            equipmentBuildsVO.setTalisman(talismanService.getTalismanById(equipmentBuilds.getAMagicWeaponId()));
            equipmentBuildsVO.setSkillTree(equipmentBuilds.getSkillTree());
            equipmentBuildsVO.setGalaxyAttribute(equipmentBuilds.getGalaxyAttribute());
            equipmentBuildsVO.setRandomValue(equipmentBuilds.getRandomValue());

            // 存到redis
            redisUtils.setEx(EQUIPMENTBUILD_KEY + ":" + id, equipmentBuildsVO, 5, TimeUnit.MINUTES);

            // 返回
            return equipmentBuildsVO;
        } catch (Exception e) {
            log.error("根据 ID 获取配装信息时出现异常，ID: {}", id, e);
            return null;
        }
    }

    /**
     * 根据配装 ID 自增点赞数量
     *
     * @param id 配装 ID
     * @return 配装信息
     */
    @Override
    public void addLikeCountStatistics(Integer id) {
        EquipmentBuilds equipmentBuilds = equipmentBuildsMapper.selectById(id);
        equipmentBuilds.setLikeCountStatistics(equipmentBuilds.getLikeCountStatistics() + 1);
        equipmentBuildsMapper.updateById(equipmentBuilds);
    }

    /**
     * 根据配装ID删除配装
     *
     * @param id
     */
    @Override
    public void deleteEquipmentBuildsById(Integer id) {
        equipmentBuildsMapper.deleteById(id);
    }

    /**
     * 获取全部配装
     *
     * @return
     */
    @Override
    public List<RecommendEquipmentBuilds> getAllEquipmentBuilds() {
        // redis查询全部配装
        List<RecommendEquipmentBuilds> recommendEquipmentBuilds = redisUtils.get(RECOMMENDEQUIPMENTBUILDS_KEY + ":all", List.class);
        if (recommendEquipmentBuilds == null || recommendEquipmentBuilds.isEmpty()) {
            // 查询数据库
            List<EquipmentBuilds> equipmentBuilds = equipmentBuildsMapper.selectList(null);
            recommendEquipmentBuilds = new ArrayList<>();
            for (EquipmentBuilds equipmentBuild : equipmentBuilds) {
                RecommendEquipmentBuilds recommendEquipmentBuild = new RecommendEquipmentBuilds();
                BeanUtils.copyProperties(equipmentBuild, recommendEquipmentBuild);
                String nickname = redisUtils.get("user:" + equipmentBuild.getUserId(), User.class).getNickname();
                log.info("nickname: {}", nickname);
                recommendEquipmentBuild.setBuildAuthor(nickname);
                recommendEquipmentBuilds.add(recommendEquipmentBuild);
            }
            redisUtils.set(RECOMMENDEQUIPMENTBUILDS_KEY + ":all", recommendEquipmentBuilds);
        }

        return recommendEquipmentBuilds;
    }

    /**
     * 新增配装
     *
     * @param equipmentBuildsDTO
     */
    @Override
    public void addEquipmentBuilds(EquipmentBuildsDTO equipmentBuildsDTO) {
        EquipmentBuilds equipmentBuilds = convertDTOToEntity(equipmentBuildsDTO);
        equipmentBuildsMapper.insert(equipmentBuilds);
    }


    /**
     * 配装DTO转化
     *
     * @param equipmentBuildsDTO
     * @return
     */
    public EquipmentBuilds convertDTOToEntity(EquipmentBuildsDTO equipmentBuildsDTO) {
        EquipmentBuilds equipmentBuilds = new EquipmentBuilds();

        EquipmentBuildsDTO.SkillTree skillTree = new EquipmentBuildsDTO.SkillTree();
        skillTree.setCriticalStrike(0);
        skillTree.setHp(0);
        skillTree.setExpertise(0);
        skillTree.setDefense(0);
        skillTree.setRecovery(0);

        // 设置基本属性，处理可能的 null 值
        equipmentBuilds.setUserId(equipmentBuildsDTO.getUserId() != null ? equipmentBuildsDTO.getUserId() : 0);
        equipmentBuilds.setBuildClass(equipmentBuildsDTO.getBuildClass() != null ? equipmentBuildsDTO.getBuildClass() : "");
        equipmentBuilds.setBuildSchool(equipmentBuildsDTO.getBuildSchool() != null ? equipmentBuildsDTO.getBuildSchool() : "");
        equipmentBuilds.setBuildName(equipmentBuildsDTO.getBuildName() != null ? equipmentBuildsDTO.getBuildName() : "");
        equipmentBuilds.setAMagicWeaponId(equipmentBuildsDTO.getAMagicWeaponId() != null ? equipmentBuildsDTO.getAMagicWeaponId() : 0);
        equipmentBuilds.setSkillTree(equipmentBuildsDTO.getSkillTree() != null ? equipmentBuildsDTO.getSkillTree() : skillTree);
        equipmentBuilds.setTalismanLevelAttribute(equipmentBuildsDTO.getTalismanLevelAttribute());
        equipmentBuilds.setStarSpirit(equipmentBuildsDTO.getStarSpirit());
        equipmentBuilds.setSetFusion(equipmentBuildsDTO.getSetFusion());
        equipmentBuilds.setGalaxyAttribute(equipmentBuildsDTO.getGalaxyAttribute());
        equipmentBuilds.setRandomValue(equipmentBuildsDTO.getRandomValue());

        List<Equipment> equipments = new ArrayList<>();
        List<Inlay> inlays = new ArrayList<>();

        if (equipmentBuildsDTO.getEquipmentBuilds() != null) {
            for (EquipmentBuildsDTO.EquipmentBuild equipmentBuild : equipmentBuildsDTO.getEquipmentBuilds()) {
                try {
                    Equipment equipment = new Equipment();
                    equipment.setId(equipmentBuild.getEquipmentId());
                    equipments.add(equipment);
                } catch (Exception e) {
                    System.err.println("获取装备信息时出现异常，装备 ID: " + equipmentBuild.getEquipmentId());
                    e.printStackTrace();
                }

                if (equipmentBuild.getInlayId() != null) {
                    for (EquipmentBuildsDTO.InlayId inlayId : equipmentBuild.getInlayId()) {
                        try {
                            Inlay inlay = new Inlay();
                            inlay.setId(inlayId.getId());
                            inlays.add(inlay);
                        } catch (Exception e) {
                            System.err.println("获取灌注符信息时出现异常，灌注符 ID: " + inlayId.getId());
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        equipmentBuilds.setEquipments(equipments);
        equipmentBuilds.setInlays(inlays);

        return equipmentBuilds;
    }


}